/*
 * @Author: zhangwenqiang
 * @Date: 2021-07-25 11:28:37
 * @LastEditors: OBKoro1
 * @LastEditTime: 2021-07-27 10:47:20
 * @FilePath: /operate/src/utils/request.js
 */
import { Message } from 'element-ui'
import store from '@/store/index'
import { getToken } from '@/utils/auth'
import settings from '@/settings'
import { isEmpty } from './common'
// import axios from 'axios'

let instance = axios.create({
  baseURL: process.env.NODE_ENV === 'development' ? '/capi' : '',
  timeout: 60000
})
let httpCode = {
  400: '请求参数错误',
  401: '登录失效，请重新登录',
  403: '服务器拒绝本次访问',
  404: '请求资源未找到',
  500: '内部服务器错误',
  501: '服务器不支持该请求使用的方法',
  502: '网关错误',
  504: '网关超时'
}
const message = (obj) => {
  let len = document.getElementsByClassName('el-message').length
  if (!len) {
    Message({
      type: 'success',
      showClose: true,
      center: true,
      ...obj
    })
  }
}
const TOKEN_KEY = 'x-session-token'
// const TOKEN_DEBUG = 'x_session_debug'
// const TOKEN_DEBUG_USERNAME = 'x_session_debug_username'
// const IS_DEBUG = process.env.NODE_ENV === 'development'
instance.interceptors.request.use(config => {
  // if (store.getters.token) {
  //   config.headers[TOKEN_KEY] = getToken()
  // }
  if (config.method === 'get') { // 防止浏览器对get请求的缓存
    config.params = {
      ...config.params,
      t: new Date().getTime()
    }
  }
  if (config.method === 'post') { // 去除输入时参数两边的空格
    if (config.data) {
      for (let key in config.data) {
        if (typeof (config.data[key]) === 'string') {
          config.data[key] = config.data[key].replace(/^\s+|\s+$/g, '')
        }
      }
    }
  }
  if (config.data && config.data._download) {
    config.timeout = 50000
    config.responseType = 'blob'
  }
  return config
}, error => {
  console.log(error)
  return Promise.reject(error)
})
instance.interceptors.response.use(response => {
  if (settings.printRequest()) {
    console.log('response from server<-', response.config.url, 'succeed')
  }
  if (response.config.url.includes('/login/verifyCode')) {
    return Promise.resolve(response.data)
  }
  if (response.config.responseType && response.config.responseType === 'blob') {
    if (response.data.type && response.data.type.startsWith('application/json')) {
      const reader = new FileReader()
      reader.onload = e => {
        let res = JSON.parse(isEmpty(e.target.result) ? '{}' : e.target.result)
        message({
          message: res.message || res.mess || '服务端未返回任何数据',
          type: 'error'
        })
      }
      reader.readAsText(response.data)
      return Promise.reject(new Error('下载文件错误'))
    } else {
      const disposition = response.headers['content-disposition']
      let fileName = response.config.data._fileName || (disposition ? disposition.split('filename=')[1] : '')
      if (!fileName) {
        const message = '服务端处理下载文件错误,无法获得文件名'
        message({
          message,
          type: 'error'
        })
        return Promise.reject(message)
      }
      fileName = decodeURIComponent(fileName)
      const content = response.data
      const blob = new Blob([content])
      if ('download' in document.createElement('a')) { // 非IE下载
        const elink = document.createElement('a')
        elink.download = fileName
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) // 释放URL 对象
        document.body.removeChild(elink)
      } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName)
      }
      return Promise.resolve({ status: 'ok', message: '已完成下载' })
    }
  }
  const { status, resultStat } = response.data
  if (status === 'ok' || resultStat === '000') {
    return Promise.resolve(response.data)
  } else {
    store.commit('user/SET_LOADING', false)
    console.log('服务端返回错误', response.config.url)
    console.log('服务端返回错误', response.data)
    message({
      message: response.data ? (response.data.message || response.data.mess) : '服务端未返回任何数据',
      type: 'error'
    })
    return Promise.reject(response.data.message || response.data.mess)
  }
}, error => {
  store.commit('user/SET_LOADING', false)
  console.log('axios request', error)
  if (error.response) {
    let tips = error.response.status in httpCode ? httpCode[error.response.status] : (error.response.data.message || error.response.data.mess)
    tips = `${tips}:${error.response.config.url}`
    message({
      message: tips,
      type: 'error'
    })
    if (error.response.status === 401) {
      store.dispatch('user/clearToken').then(() => {
        location.reload()
      })
    }
    return Promise.reject(error)
  } else {
    message({
      message: error.toString(),
      type: 'error'
    })
    return Promise.reject(new Error(error.toString()))
  }
})
export let get = (url, params, config = {}) => {
  return instance({
    method: 'get',
    url,
    params,
    ...config
  }).then(response => {
    return Promise.resolve(response)
  }).catch(error => {
    return Promise.reject(error)
  })
}
export let post = (url, data, config = {}) => {
  return instance({
    method: 'post',
    url,
    data,
    ...config
  }).then(response => {
    return Promise.resolve(response)
  }).catch(error => {
    return Promise.reject(error)
  })
}

export let put = (url, data, config = {}) => {
  return instance({
    method: 'put',
    url,
    data,
    ...config
  }).then(response => {
    return Promise.resolve(response)
  }).catch(error => {
    return Promise.reject(error)
  })
}

export function createRequest (searchUrl, searchMethod = 'post') {
  const fetch = (params) => {
    let requestObject = null
    const method = searchMethod.toLowerCase()
    if (method === 'get') {
      requestObject = instance[method](searchUrl, { params })
    } else {
      requestObject = instance[method](searchUrl, params)
    }
    return requestObject
  }
  return fetch
}

export default instance
